<?php

namespace App\Http\Controllers\Xiamenguoji;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Services\AesEncrypt;
use Illuminate\Support\Facades\Log;

class XiamenguojiSynchronizationController extends Controller
{
    private $config = [
        'RSA_PUBLIC' => '',
        'RSA_PRIVATE' => '',
        'platNo' => 'XIB-B-SDJCS-77763' //平台编号
    ];
	/**
     * 测试
     * @param $phone
     * @return mixed
     */
	public function test()
	{
		echo 1;        
	}
	
	/**
	 * 数据同步（厦门国际）
	 * 数据组装
	 * 创建交易订单
	 */
	 public function store() {
	   //  前一天时间
	    $begin = date("Y-m-d 00:00:00", strtotime("-1 day")); 
	    $end = date("Y-m-d 23:59:59", strtotime("-1 day"));
        $res = Db::table('agent_top_up_orders')
                ->where('synchro_status','!=', 2)
                ->whereBetween('created_at', [$begin, $end])
                ->limit(1000)
                ->get();
        $total = count($res);
        if($total == 0) {//顺利执行
            Self::payOrderStore();
            die;
        };
        if (!isset($numberOfTime)) {
            $num = Db::table('agent_top_up_orders')
                ->where('synchro_status','!=', 2)
                ->whereBetween('created_at', [$begin, $end])
                ->count();
            if ($num >= 1000) {
                // 超过limit数据，则设置多5次查询次数
                $numberOfTime = ceil($num/1000) + 5;
                // continue;
            } else {
                // 有问题数据时，重新执行次数
                $numberOfTime = 5;
            }
        } else {
            if ($numberOfTime <= 0) {
                Self::payOrderStore();
                die;
            };
            $numberOfTime--;
        }
        
        
        foreach ($res as $key => $val) {
            $transId = date('YmdHis',time()).rand(1000,9999);
        	//业务报文
        	$arr = array(
        		'platNo' => $this->config['platNo'],
        		'transId' => $transId,
        		'orderNum' => 1,
        		'orderList' => array(
        		    array('platOrderNo' => $val->order_id,
        		    'platOrderInfo' => '代理商账户余额充值',
        		    'transAmt' => number_format(round($val->amount / 100, 2), 2,".",""), // 渠道要求字符串
        		    'guaranteeType' => 1,
        		    'sellerId' => '643503872760872960')
        		 )
        	);
        // 	print_r($arr);die;
        	$addTransactionOrder = Self::addTransactionOrder($arr);
        // 	print_r($addTransactionOrder);die;
        	if($addTransactionOrder == 'ok') {
        	    $affected = DB::table('agent_top_up_orders')
                          ->where('id', $val->id)
                          ->update(['synchro_status' => 2]);


        	} else {
                echo "日志";
                Log::info('数据同步异常: ' . $addTransactionOrder);
            }
            $total--;
            // 数据传输完一批后，看是否有下一批需要传
            if ($total == 0) {
                Self::store();
            }
        	// var_dump($arr);
        	// die;
        }
        
	 }
	 
	 /**
	 * 数据同步（厦门国际）
	 * 数据组装
	 * 创建交易订单
	 */
	 public function payOrderStore() {
	     //  前一天时间
	    $begin = date("Y-m-d 00:00:00", strtotime("-1 day")); 
	    $end = date("Y-m-d 23:59:59", strtotime("-1 day"));
	   // echo $begin."<br/>".$end;die;
        $res = Db::table('payment_orders')
                ->whereBetween('created_at', [$begin, $end])
                ->where(function($query) {
                    $query->where('synchro_pay_status','!=', 2)
                          ->orWhere('synchro_status','!=', 2);
                })
                ->limit(1000)
                ->get();
        // print_r($res);die;
        $total = count($res);
        if($total == 0) {//顺利执行
            // Self::payOrderStore();
            die;
        };
        if (!isset($numberOfTime)) {
            $num = Db::table('payment_orders')
                ->whereBetween('created_at', [$begin, $end])
                ->count();
            if ($num >= 1000) {
                // 超过limit数据，则设置多5次查询次数
                $numberOfTime = ceil($num/1000) + 5;
                // continue;
            } else {
                // 有问题数据时，重新执行次数
                $numberOfTime = 5;
            }
        } else {
            if ($numberOfTime <= 0) {
                // Self::payOrderStore();
                die;
            };
            $numberOfTime--;
        }
        // echo $numberOfTime;die;
                // echo count($res);
        // print_r($res);
        foreach ($res as $key => $val) {
            $transId = date('YmdHis',time()).rand(1000,9999);
        	//业务报文

        	$arr = array(
        		'transId' => $transId,
        		'platPayId' => $val->order_id,
        		'orderType' => 2,//支付订单类型 1-预付货款充值订单 2-支付订单
        		'transAmt' => number_format(round($val->amount / 100, 2), 2,".",""),
        		// 'notifyUrl'=>'https://baidu.com',
                'notifyUrl' => url('/api/h5/bank/account-notify'),
                'returnUrl' => url('h5/my'),
        		'platNo' => $this->config['platNo'],
        		// 'returnUrl'=>'https://baidu.com',
        		'platOrderNos' => $val->business_order_id
    	    );
        // 	print_r($arr);die;
        // 	$addPayOrder = Self::addPayOrder($arr);
            
        // // 	print_r($addPayOrder);die;
        // 	if($addPayOrder == 'ok') {
        // 	    $affected = DB::table('payment_orders')
        //                   ->where('id', $val->id)
        //                   ->update(['synchro_status' => 2]);
                
        //         // else {
        //         //     echo "日志";
        //         //     continue;
        //         // }
        // 	} else {
        // 	    echo "日志";
        // 	}
        	$addStatusOrder = Self::addStatusOrder($arr);
            if($addStatusOrder == 'ok') {
                $affected = DB::table('payment_orders')
                          ->where('id', $val->id)
                          ->update(['synchro_pay_status' => 2]);


            } else {
                echo "日志";
            }
        	$total--;
            // 数据传输完一批后，看是否有下一批需要传
            if ($total == 0) {
                Self::payOrderStore();
            }
            echo "日志";
            //  die;
            continue;

        }
	 }
	 
	 /**
	  * 创建交易订单
	  * 
	  * 
	  */
	  public function addTransactionOrder($data) {
	   //   print_r($data);
	      $api = '/IESI111007'; //创建交易订单
	      
	      $signdata = Self::postData($data);
	      print_r($signdata);
    	  $result = Self::postUrl($api,$signdata);
    	  print_r($result);
	      $ok = Self::verifyData($result);
	      $returnData = json_decode($ok, true);
	      print_r($returnData['retCode']);
	      if($returnData['retCode'] == '00000' || $returnData['retCode'] == 'E010110130') {
	          return 'ok';
	      }
	      return $ok;
	  }
	  
	  /**
	  * 创建支付订单
	  * 
	  * 
	  */
	  public function addPayOrder($data) {
	    $api = '/IESI111008'; //创建支付订单
    	print_r($data);
    	$signdata = Self::postData($data);
    	print_r($signdata);
    // 	print_r($data);
        $result = Self::postUrl($api,$signdata);
        $ok = Self::verifyData($result);
        $returnData = json_decode($ok, true);
        // print_r($returnData);
        if($returnData['retCode'] == '00000' || $returnData['retCode'] == 'E010110130') {
              return 'ok';
          }
        return $returnData['retCode'];
	  }
	  
	  /**
	  * 支付订单状态同步
	  * 
	  * 
	  */
	  public function addStatusOrder($data) {
	      $api = '/IESI111047'; //支付订单状态同步
            $arr = array(
             'platNo'=>$data['platNo'],
             'transId'=>$data['transId'],
             'platPayId'=>$data['platPayId'],
             'payCode'=>'095',
             'merchOrderNo'=>$data['platOrderNos'],
            );
            // print_r($arr);
            // die;
            $signdata = Self::postData($arr);
            print_r($signdata);
        //  print_r($arr);
            $result = Self::postUrl($api,$signdata);
            $ok = Self::verifyData($result);
            $returnData = json_decode($ok, true);
            print_r($returnData);
            if($returnData['retCode'] == '00000' || $returnData['retCode'] == 'E010110079') {
              return 'ok';
            }
            return $returnData['retCode'];
	  }
	  
	  /**
	   * 组装发送数据
	   * 
	   */
	  public function postData($data) {
	   //   var_dump($data);echo "bbbbbbb".rand(0,1000);
	   //   die;
	       $timestamp = Carbon::now()->format('YmdHis');
	       $plainKey = substr(md5(uniqid(microtime(true),true)),16);//16位随机key
	       //echo $plainKey."</br>";
	       $strs="QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm";
           $serialNo=substr(str_shuffle($strs),mt_rand(0,strlen($strs)-11),15);
	       //$serialNo = substr(md5(uniqid(microtime(true),true)),13);//15位技术流水号
        //   echo $serialNo;die;
        //   $plainKey="57e4668168d0b8e1";
	       $aes = new AesEncrypt($plainKey);
           $plaintext=json_encode($data);
        //   print_r($plaintext);die;
           $encrypted = $aes->encrypt($plaintext);
        //   print_r($encrypted);
        //   $this->config['RSA_PUBLIC'] = file_get_contents(resource_path('sms/public.pem'));
           // print_r($this->config['RSA_PUBLIC']);
           //请求时，对手公钥加密
           $public_key = openssl_pkey_get_public(file_get_contents(resource_path('sms/public.pem')));
            // print_r($public_key);
            // die;
           if(!$public_key){
        	    die('公钥不可用');
            }
        	//第一个参数是待加密的数据只能是string，第二个参数是加密后的数据,第三个参数是openssl_pkey_get_public返回的资源类型,第四个参数是填充方式
        
        	$return_en = openssl_public_encrypt($plainKey, $crypted, $public_key);
        	if(!$return_en){
        	    return('加密失败,请检查RSA秘钥');
        	}
        	$eb64_cry = base64_encode($crypted);
        	$array=array(
        	    "encryptedData"=>$encrypted,
                "encryptedKey"=>$eb64_cry,
                "serialNo"=>$serialNo,
                 "timestamp"=>$timestamp,
                 "version"=>"2.0"
                );
            $content=json_encode($array);
            //注意php的转义字符
            $content=stripcslashes($content);
            // $privateKey = file_get_contents(resource_path('sms/xxx_pri.key'));
            $privateKey = "MIICXQIBAAKBgQC7J83ZEL/s+VSZv5wbBCMKLPQueRV13Zd4DwSxui/Hqedx5iO3yeG7go/oP8by/cQfOEMdM7ypdO12GCmQmvx5dyIrvZTJIyZ6RTZ4DNN0rRnqYVFWyoTs5F9xMxx/SiAPviRpRmDBBNqLYFZ+aedtO0adinvTy/SNXWyj/mFH/wIDAQABAoGAaNYgKfKHABCegk1h/YQwuJd75Lhw/Ag3u8n14DSiZR7YheXbpi0RJH87a2amZCEghjh259m+WdIk3l0kk1suB0ojkTsXXZbut1kYz1Vnz1adA+PJ8KpYQwu6YIxz6y6A1jcVflXfe4fC+tH+bO2jjm2uk/K6Ahyh8jge5AYxdbECQQDv05UNhX1Rgtkmaw2oeZcS4JEFb/tntAojQFmIo17yP7IFubxYG4Dsy4ugHqX1OdmmTiZQC8A9sepQYSegBX13AkEAx8bl2+Wzv4i88D05qRRpmOH2SEsSApHdUnqPeEoWH9MABQAehlAB6uU3qBwD6dk1YHQ2CC5Pvtm3ZFDnpYaLuQJBAJTi98/zJX+rCgCNyWbkRWPUwnNrt9oDrZ+A3ZS0R8eAv5ZKXqEcQge/vajkHgeFqJdUQPjEss4aW+sWxbDUd7UCQQCcoM5aZ29T/arUV8w7Seu4l4B2EZVfOmlhXwHY94z9Cnr7cKp994BpX6kRPlW7JDb7FmG+bEDNiviDyAK1/hTRAkBPD/yCTwwJRqkOPwpeM0WOOCkZR2AnleNywfxOVWs8sRHazcMAw2XatfgZJz2VJcw4Q8DCHllB6BGkOEw+uqDi";
            $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($privateKey, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
            $key = openssl_get_privatekey($privateKey);
            // print_r($key);
            // die;
            //计算签名
            openssl_sign($content, $signature, $key, "SHA256");
            openssl_free_key($key);
            $sign = base64_encode($signature);
            $signature=stripcslashes($sign);
            // echo "sign:".$signature;
            // return $signature;
            $signdata = '{
                "signature":"'.$signature.'",
            	"encryptedKey":"'.$eb64_cry.'",
            	"encryptedData":"'.$encrypted.'",
            	"version":"2.0",
            	"serialNo":"'.$serialNo.'",
            	"timestamp":"'.$timestamp.'"}';
            return $signdata;
            // return Self::addTransactionOrder($baseUrl,$signdata);
           
	  }
	  
	  /**
	   * 调用接口
	   * 
	   */
	   public function postUrl($url, $data) {
            
            $baseUrl = 'https://xib03.test.xib.com.cn:8082/ifspesi/tfs/v2/api/'.$this->config['platNo'];
            $requestUrl = $baseUrl.$url;
    		$cu = curl_init();
    		curl_setopt($cu, CURLOPT_URL, $requestUrl);
    		// curl_setopt($cu, CURLOPT_HEADER, 0);
    		curl_setopt($cu, CURLOPT_CUSTOMREQUEST, "POST");
    		curl_setopt($cu, CURLOPT_RETURNTRANSFER, true);
    		// curl_setopt($cu, CURLOPT_CONNECTTIMEOUT, 10);
    		curl_setopt($cu, CURLOPT_HTTPHEADER, 
    			array('Content-Type: application/json', 'Content-Length: ' . strlen($data)));
    		curl_setopt($cu, CURLOPT_POST, 1);
    		curl_setopt($cu, CURLOPT_SSL_VERIFYPEER, false);
    		curl_setopt($cu, CURLOPT_POSTFIELDS, $data);
    		$res = curl_exec($cu);
    		return $res;
    	}
    	
    	/**
    	 * 验签
    	 * 
    	 */
    	public function verifyData($data) {
    	   
    	    $a = json_decode($data, true);
        	print_r($a);
        	$signData = $a['signature'];
            unset($a['signature']);
            $publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA53T+H/rbmgvuuqx7ZZkwaJZSKnfelyDHle+gURy2286K6VxG+BspXCCYFwmqhBzM1qX1klTCspHX6/9yUFc2mxUXKqCh8a84lu/Rv2aLhogfro+bzgOYE/LmPg+wJ/cqz8WXcdrPozLhg7/5RIvy6mcwKpT2rVwA4p1APcj63PxU8UdxUlw6hOfV9aKFQvhWq7ZvZJeRwwsRFplS4wetaHom9VWDjJK1F1tzgwtq0PtjfesgC1mf/2v5rQ6HH/X1K6Y478LIXcaO73mPd24N7VkhM7HOPVTBcVKdZKd3C7v/Th3Vtme3yvlg/0leuWXhgRuhLwbA4oMkEshaccle2QIDAQAB";
            $digest = Self::arraySort($a);
            $content=stripcslashes(json_encode(($digest)));
            echo "签名原文:$content";
            $signature = $signData;
               //注意php的转义字符
            $signature=stripcslashes($signature);
            $publicKey = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($publicKey, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";
            $key = openssl_get_publickey($publicKey);
            $ok = openssl_verify($content,base64_decode($signature), $key, 'SHA256');
            openssl_free_key($key);
            //结果:1
        	echo  "验签成功?$ok \n";
        	$this->config['RSA_PRIVATE'] = file_get_contents(resource_path('sms/private.pem'));
            //请求时，对手公钥加密
            $private_key = openssl_pkey_get_private($this->config['RSA_PRIVATE']);
            if(!$private_key){
                die('私钥不可用');
            }
            $encryptedKey = $a['encryptedKey'];
            $return_de = openssl_private_decrypt(base64_decode($encryptedKey), $decrypted, $private_key);
            if(!$return_de){
                return('解密失败,请检查RSA秘钥');
            }
            echo "私钥解密数据:".$decrypted;//e36425fe39e70fb
         //使用随机key解密返回的加密业务数据报文
            $retAes = new AesEncrypt($decrypted);
            $retEncrypted = $a['encryptedData'];
            $decrypted = $retAes->decrypt($retEncrypted);
        
            echo '要解密的响应业务数据报文：', $retEncrypted, '<br>解密后的业务数据报文：', $decrypted;
            return $decrypted;
    	}
    	
    	
    	public function arraySort($data)
        {
            // 排序
            ksort($data);
            $str = '';
            foreach ($data as $k => $v) {
                if (is_array($v)) {
                    $t = Self::array2string($v);
                } else {
                    $t = $v;
                }
                $str .= '|' . $t;
            }
    
            return substr($str, 1);
        }
        public function array2string($array)
        {
            $string = '[';
            if ($array && is_array($array)) {
                foreach ($array as $key => $value) {
                    if ($value && is_array($value)) {
                        if ($key != 0) {
                            $string .= ', {';
                        } else {
                            $string .= '{';
                        }
                        $string_s = [];
                        foreach ($value as $k => $v) {
                            $string_s[] .= ' ' . $k . '=' . $v;
                        }
                        $stringc = implode(',', $string_s);
                        $stringc = substr($stringc, 1);
                        $string .= $stringc;
                        $string .= '}';
                    }
                }
            }
            $string .= ']';
    
            return $string;
    }
}